package ru.spb.osll.myfit.server.execute;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;

import ru.spb.osll.myfit.common.ProgressCounts;
import ru.spb.osll.myfit.common.Table;
import ru.spb.osll.myfit.server.parser.TableParser;
import fit.Counts;
import fit.Parse;

public class FixtureListenerImpl implements ProgressFixtureListener {
  private Logger log = Logger.getLogger(getClass());
  private List<Table> m_tables = new LinkedList<Table>();
  private TableParser m_tableParser;
  private ProgressCounts m_counts;
  private ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

  public FixtureListenerImpl(TableParser tableParser) {
    m_tableParser = tableParser;
    m_counts = new ProgressCounts();
  }

  @Override
  public void tableFinished(Parse table) {
    Table newTable = m_tableParser.parse(table);
    if (newTable != null) {
      m_tables.add(newTable);
      m_counts.setProgressSegments(m_counts.getProgressSegments() + 1);
    }

    try {
      byte[] bytes = readTable(table);
      if (bytes.length > 0) {
        outputStream.write(bytes);
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Override
  public void tablesFinished(Counts arg0) {
    log.info("Counts: " + arg0.toString());
  }

  public List<Table> getTables() {
    return Collections.unmodifiableList(m_tables);
  }

  public void setCounts(Counts counts) {
    m_counts.setCounts(counts.right, counts.wrong, counts.ignores,
        counts.exceptions);
  }

  public ProgressCounts getCounts() {
    return m_counts;
  }

  public void countTotalTablesQuantity(Parse tables) {
    int totalTables = 0;
    Table newTable;
    tables = tables.more;
    while (tables != null) {
      newTable = m_tableParser.parse(tables);
      if (newTable != null) {
        totalTables++;
      }
      tables = tables.more;
    }
    m_counts.setTotalSegments(totalTables);
  }

  private byte[] readTable(Parse table) throws IOException {
    ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
    OutputStreamWriter streamWriter = new OutputStreamWriter(byteBuffer,
        "UTF-8");
    PrintWriter writer = new PrintWriter(streamWriter);
    Parse more = table.more;
    table.more = null;
    if (table.trailer == null)
      table.trailer = "";
    table.print(writer);
    table.more = more;
    writer.close();
    return byteBuffer.toByteArray();
  }

  public ByteArrayOutputStream getOutputStream() {
    return outputStream;
  }
}
